home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1995 #5 & #6
/
Amiga Plus CD - 1995 - No. 5 and 6.iso
/
pd
/
netz
/
term
/
extras
/
source
/
term-source.lha
/
termVerify.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-17
|
14KB
|
784 lines
/*
** termVerify.c
**
** Check if files/drawers/programs are where they should be
**
** Copyright © 1990-1995 by Olaf `Olsen' Barthel
** All Rights Reserved
**
** :ts=4
*/
#include "termGlobal.h"
struct Path
{
BPTR path_Next,
path_Lock;
};
/* FindPath(struct Window *Parent,STRPTR Path,BOOLEAN CanCreate,LONG *Error):
*
* For the complete path of a file, this checks if the
* path leading to the file actually exists. This is
* primarily for files the program should create. Thus,
* the file in question may not yet exist.
*/
BOOLEAN __regargs
FindPath(struct Window *Parent,STRPTR Path,BOOLEAN CanCreate,LONG *Error)
{
UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
STRPTR Index;
strcpy(LocalBuffer,Path);
Index = PathPart(LocalBuffer);
*Index = 0;
return(FindDrawer(Parent,LocalBuffer,CanCreate,Error));
}
/* FindDrawer(struct Window *Parent,STRPTR Drawer,BOOLEAN CanCreate,LONG *Error):
*
* Check if a given drawer exists and give
* the user the choice to create it if necessary.
*/
BOOLEAN __regargs
FindDrawer(struct Window *Parent,STRPTR Drawer,BOOLEAN CanCreate,LONG *Error)
{
APTR OldPtr = ThisProcess -> pr_WindowPtr;
BPTR FileLock;
BOOLEAN Result = FALSE;
LONG LocalError;
if(!Config -> MiscConfig -> ProtectiveMode)
return(TRUE);
if(!Error)
Error = &LocalError;
// Lock out DOS requesters
ThisProcess -> pr_WindowPtr = (APTR)-1;
// Does the drawer exist?
if(FileLock = Lock(Drawer,ACCESS_READ))
{
struct FileInfoBlock __aligned FileInfo;
// Take a closer look
if(Examine(FileLock,&FileInfo))
{
// Is this actually a file?
if(FileInfo . fib_DirEntryType < 0)
*Error = ERR_NOT_A_DRAWER;
else
{
*Error = 0;
Result = TRUE;
}
}
else
*Error = IoErr();
UnLock(FileLock);
}
else
{
LONG Result2 = IoErr();
// If it doesn't exist, see if we should ask the user to create it
if(Result2 == ERROR_OBJECT_NOT_FOUND && Parent && CanCreate)
{
UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
STRPTR Index;
BOOLEAN CanCreate = FALSE;
// Chop off the last path part
strcpy(LocalBuffer,Drawer);
Index = PathPart(LocalBuffer);
*Index = 0;
// Get a lock on the parent drawer
if(FileLock = Lock(LocalBuffer,ACCESS_READ))
{
struct InfoData __aligned InfoData;
// Inquire volume information
if(Info(FileLock,&InfoData))
{
// Can we write to this volume?
if(InfoData . id_DiskState == ID_VALIDATED)
CanCreate = TRUE;
}
UnLock(FileLock);
}
// Give it a try?
if(CanCreate)
{
LT_LockWindow(Parent);
// Ask if we should create it
if(MyEasyRequest(Parent,LocaleString(MSG_VERIFY_NO_DRAWER_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Drawer))
{
if(FileLock = CreateDir(Drawer))
{
Result2 = 0;
Result = TRUE;
UnLock(FileLock);
}
else
Result2 = IoErr();
}
else
{
Result2 = 0;
Result = TRUE;
}
LT_UnlockWindow(Parent);
}
}
*Error = Result2;
}
ThisProcess -> pr_WindowPtr = OldPtr;
if(Window && !Result && *Error)
{
LT_LockWindow(Parent);
if(*Error == ERR_NOT_A_DRAWER)
ShowError(Parent,*Error,NULL,Drawer);
else
ShowError(Parent,ERR_DRAWER_NOT_FOUND,*Error,Drawer);
LT_UnlockWindow(Parent);
}
return(Result);
}
/* FindFile(struct Window *Parent,STRPTR File,LONG *Error):
*
* Try to locate a file.
*/
BOOLEAN __regargs
FindFile(struct Window *Parent,STRPTR File,LONG *Error)
{
APTR OldPtr = ThisProcess -> pr_WindowPtr;
BPTR FileLock;
BOOLEAN Result = FALSE;
LONG LocalError;
if(!Config -> MiscConfig -> ProtectiveMode)
return(TRUE);
if(!Error)
Error = &LocalError;
// Lock out DOS requesters
ThisProcess -> pr_WindowPtr = (APTR)-1;
// Try to get a lock on the file
if(FileLock = Lock(File,ACCESS_READ))
{
struct FileInfoBlock __aligned FileInfo;
// Take a closer look
if(Examine(FileLock,&FileInfo))
{
// Is it actually a drawer?
if(FileInfo . fib_DirEntryType > 0)
*Error = ERR_NOT_A_FILE;
else
{
*Error = 0;
Result = TRUE;
}
}
else
*Error = IoErr();
UnLock(FileLock);
}
else
*Error = IoErr();
ThisProcess -> pr_WindowPtr = OldPtr;
if(Window && !Result && *Error)
{
LT_LockWindow(Parent);
if(*Error == ERR_NOT_A_FILE)
ShowError(Parent,*Error,NULL,File);
else
ShowError(Parent,ERR_FILE_NOT_FOUND,*Error,File);
LT_UnlockWindow(Parent);
}
return(Result);
}
/* FindARexxComment(STRPTR LocalBuffer,LONG Len):
*
* Check for a valid ARexx file comment.
*/
STATIC BOOLEAN __regargs
FindARexxComment(STRPTR LocalBuffer,LONG Len)
{
register WORD i;
register UBYTE c;
for(i = 0 ; i < Len - 1 ; i++)
{
c = LocalBuffer[i];
// Stop on invalid characters.
if((c < ' ' && c != '\r' && c != '\n' && c != '\a') || (c >= 127 && c < 160))
break;
else
{
// Looks like the typical
// introductory comment line.
if(c == '/' && LocalBuffer[i + 1] == '*')
return(TRUE);
}
}
return(FALSE);
}
/* FindProgram(struct Window *Parent,STRPTR Program,LONG *Error):
*
* Try to find a program given by name. Firstly, try to access the
* file by its name. If unsuccessful, search the Shell path list.
* As a last resort, search the global AmigaDOS resident program
* list. Note that while this routine may fail program execution
* may still work. WShell for example maintains its own internal
* resident list.
*/
BOOLEAN __regargs
FindProgram(struct Window *Parent,STRPTR Program,LONG *Error)
{
UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
APTR OldPtr = ThisProcess -> pr_WindowPtr;
BPTR FileLock;
WORD i;
BOOLEAN Result = FALSE,
CanExecute = FALSE;
LONG LocalError;
if(!Config -> MiscConfig -> ProtectiveMode)
return(TRUE);
if(!Error)
Error = &LocalError;
// Chop off the program arguments
strcpy(LocalBuffer,Program);
for(i = 0 ; i < strlen(LocalBuffer) ; i++)
{
if(LocalBuffer[i] == ' ')
{
LocalBuffer[i] = 0;
break;
}
}
Program = LocalBuffer;
// Lock out DOS requesters
ThisProcess -> pr_WindowPtr = (APTR)-1;
// Try to lock the program
if(FileLock = Lock(Program,ACCESS_READ))
{
struct FileInfoBlock __aligned FileInfo;
// Take a closer look
if(Examine(FileLock,&FileInfo))
{
// Is it actually a drawer?
if(FileInfo . fib_DirEntryType > 0)
*Error = ERR_NOT_A_FILE;
else
{
// So far, so good
*Error = 0;
Result = TRUE;
// Is it marked as being executable?
if(!(FileInfo . fib_Protection & FIBF_EXECUTE))
{
BPTR FileHandle;
ULONG Value;
// Look at the contents
if(FileHandle = Open(Program,MODE_OLDFILE))
{
if(Read(FileHandle,&Value,sizeof(ULONG)) == sizeof(ULONG))
{
// Not a failproof check, but better than nothing
if(Value == HUNK_HEADER)
CanExecute = TRUE;
}
Close(FileHandle);
}
}
else
{
// Does it have the script bit set? */
if(FileInfo . fib_Protection & FIBF_SCRIPT)
CanExecute = TRUE;
else
{
BPTR FileHandle;
// Now check if it's an ARexx script.
if(FileHandle = Open(Program,MODE_OLDFILE))
{
UBYTE LocalBuffer[256];
LONG Len;
if((Len = Read(FileHandle,LocalBuffer,256)) > 0)
{
if(CanExecute = FindARexxComment(LocalBuffer,Len))
Result = TRUE;
}
Close(FileHandle);
}
}
}
}
}
UnLock(FileLock);
}
else
{
LONG Result2 = IoErr();
if(Result2 == ERROR_DEVICE_NOT_MOUNTED)
*Error = ERROR_OBJECT_NOT_FOUND;
else
*Error = Result2;
}
// Give it another try
if(!Result || !CanExecute)
{
// Take care
if(ThisProcess -> pr_CLI)
{
struct CommandLineInterface *CLI = BADDR(ThisProcess -> pr_CLI);
BPTR StartCD,
Drawer;
struct Path *Path;
BOOLEAN InitialCD = TRUE,
GotIt = FALSE;
// Run down the Shell path search list
for(Path = BADDR(CLI -> cli_CommandDir) ; Path && !GotIt ; Path = BADDR(Path -> path_Next))
{
Drawer = CurrentDir(Path -> path_Lock);
if(InitialCD)
{
StartCD = Drawer;
InitialCD = FALSE;
}
// Try to lock the program
if(FileLock = Lock(Program,ACCESS_READ))
{
struct FileInfoBlock __aligned FileInfo;
// Take a closer look
if(Examine(FileLock,&FileInfo))
{
// Is this a file marked as being executable?
if(FileInfo . fib_DirEntryType < 0)
{
if(!(FileInfo . fib_Protection & FIBF_EXECUTE))
{
BPTR FileHandle;
ULONG Value;
// Look at the contents
if(FileHandle = Open(Program,MODE_OLDFILE))
{
if(Read(FileHandle,&Value,sizeof(ULONG)) == sizeof(ULONG))
{
// Not a failproof check, but better than nothing
if(Value == HUNK_HEADER)
GotIt = TRUE;
}
Close(FileHandle);
}
}
else
{
// Does it look like a script?
if(FileInfo . fib_Protection & FIBF_SCRIPT)
GotIt = TRUE;
}
}
}
UnLock(FileLock);
}
}
if(!GotIt)
{
BPTR CommandDir = Lock("C:",ACCESS_READ);
Drawer = CurrentDir(CommandDir);
if(InitialCD)
{
StartCD = Drawer;
InitialCD = FALSE;
}
// Try to lock the program
if(FileLock = Lock(Program,ACCESS_READ))
{
struct FileInfoBlock __aligned FileInfo;
// Take a closer look
if(Examine(FileLock,&FileInfo))
{
// Is this a file marked as being executable?
if(FileInfo . fib_DirEntryType < 0)
{
if(!(FileInfo . fib_Protection & FIBF_EXECUTE))
{
BPTR FileHandle;
ULONG Value;
// Look at the contents
if(FileHandle = Open(Program,MODE_OLDFILE))
{
if(Read(FileHandle,&Value,sizeof(ULONG)) == sizeof(ULONG))
{
// Not a failproof check, but better than nothing
if(Value == HUNK_HEADER)
GotIt = TRUE;
}
Close(FileHandle);
}
}
else
{
// Does it look like a script?
if(FileInfo . fib_Protection & FIBF_SCRIPT)
GotIt = TRUE;
}
}
}
UnLock(FileLock);
}
UnLock(CommandDir);
}
if(!InitialCD)
CurrentDir(StartCD);
if(GotIt)
{
CanExecute = TRUE;
*Error = 0;
Result = TRUE;
}
}
}
// As a last resort, scan the resident program list
if(!Result)
{
Forbid();
if(FindSegment(Program,NULL,FALSE))
{
CanExecute = TRUE;
*Error = 0;
Result = TRUE;
}
Permit();
}
// Last check for ARexx script.
if(!Result)
{
UBYTE RexxName[MAX_FILENAME_LENGTH];
strcpy(RexxName,"REXX:");
if(AddPart(RexxName,Program,MAX_FILENAME_LENGTH))
{
BPTR FileHandle;
// Now check if it's an ARexx script.
if(FileHandle = Open(RexxName,MODE_OLDFILE))
{
UBYTE LocalBuffer[256];
LONG Len;
if((Len = Read(FileHandle,LocalBuffer,256)) > 0)
{
if(CanExecute = FindARexxComment(LocalBuffer,Len))
Result = TRUE;
}
Close(FileHandle);
}
}
}
// Last check for AmigaDOS script
if(!Result)
{
UBYTE ScriptName[MAX_FILENAME_LENGTH];
strcpy(ScriptName,"S:");
if(AddPart(ScriptName,Program,MAX_FILENAME_LENGTH))
{
BPTR FileLock;
if(FileLock = Lock(ScriptName,ACCESS_READ))
{
struct FileInfoBlock __aligned FileInfo;
if(Examine(FileLock,&FileInfo))
{
if(FileInfo . fib_DirEntryType < 0 && (FileInfo . fib_Protection & FIBF_SCRIPT) && FileInfo . fib_Size > 0)
CanExecute = Result = TRUE;
}
UnLock(FileLock);
}
}
}
if(!CanExecute && Result)
{
*Error = ERROR_NOT_EXECUTABLE;
Result = FALSE;
}
ThisProcess -> pr_WindowPtr = OldPtr;
if(Window && !Result && *Error)
{
LT_LockWindow(Parent);
if(*Error == ERR_NOT_A_FILE)
ShowError(Parent,*Error,NULL,Program);
else
ShowError(Parent,ERR_PROGRAM_NOT_FOUND,*Error,Program);
LT_UnlockWindow(Parent);
}
return(Result);
}
/* FindLibDev(struct Window *Parent,STRPTR File,LONG Type,LONG *Error):
*
* Try to locate a file.
*/
BOOLEAN __regargs
FindLibDev(struct Window *Parent,STRPTR File,LONG Type,LONG *Error)
{
UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
STRPTR OriginalFile;
APTR OldPtr = ThisProcess -> pr_WindowPtr;
BPTR FileLock;
BOOLEAN Result = FALSE,
Replaced = FALSE;
LONG LocalError;
struct Node *Node;
if(!Config -> MiscConfig -> ProtectiveMode)
return(TRUE);
if(!Error)
Error = &LocalError;
Forbid();
if(Type == NT_LIBRARY)
Node = FindName(&SysBase -> LibList,PathPart(File));
else
Node = FindName(&SysBase -> DeviceList,PathPart(File));
Permit();
if(Node)
{
*Error = 0;
return(TRUE);
}
// Lock out DOS requesters
ThisProcess -> pr_WindowPtr = (APTR)-1;
// Try to get a lock on the file
Look:
if(FileLock = Lock(File,ACCESS_READ))
{
struct FileInfoBlock __aligned FileInfo;
// Take a closer look
if(Examine(FileLock,&FileInfo))
{
// Is it actually a drawer?
if(FileInfo . fib_DirEntryType > 0)
*Error = ERR_NOT_A_FILE;
else
{
if(ValidateFile(File,Type,NULL))
{
*Error = 0;
Result = TRUE;
}
else
*Error = ERROR_OBJECT_WRONG_TYPE;
}
}
else
*Error = IoErr();
UnLock(FileLock);
}
else
*Error = IoErr();
if(!Result && !Replaced)
{
Replaced = TRUE;
if(Type == NT_LIBRARY)
strcpy(LocalBuffer,"Libs:");
else
strcpy(LocalBuffer,"Devs:");
OriginalFile = File;
if(AddPart(LocalBuffer,File,MAX_FILENAME_LENGTH))
{
File = LocalBuffer;
goto Look;
}
}
if(Replaced)
File = OriginalFile;
ThisProcess -> pr_WindowPtr = OldPtr;
if(Window && !Result && *Error)
{
LT_LockWindow(Parent);
if(*Error == ERR_NOT_A_FILE)
ShowError(Parent,*Error,NULL,File);
else
ShowError(Parent,ERR_FILE_NOT_FOUND,*Error,File);
LT_UnlockWindow(Parent);
}
return(Result);
}